// types.ts
export interface AppConfig {
  ios: string;
  package: string;
  scheme: string;
  timeout?: number;
}

export interface AppSchemes {
  [key: string]: {
    ios: string;
    android: string;
  };
}

export interface StoreSchemes {
  [key: string]: string;
}

// constants.ts
export const APP_SCHEMES: AppSchemes = {
  meituan: {
    ios: '423084029',
    android: 'com.sankuai.meituan'
  },
  dianping: {
    ios: '351091731',
    android: 'com.dianping.v1'
  },
  gaode: {
    ios: '461703208',
    android: 'com.autonavi.minimap'
  },
  weixin: {
    ios: '836500024',
    android: 'com.tencent.mm'
  },
  douyin: {
    ios: '1142110895',
    android: 'com.ss.android.ugc.aweme'
  }
};

export const STORE_SCHEMES: StoreSchemes = {
  apple: "itms-apps://apps.apple.com/cn/app/id",
  huawei: "appmarket://details?id=",
  vivo: "vivoMarket://details?id=",
  oppo: "market://details?id=",
  xiaomi: "mimarket://details?id=",
  oneplus: "oneplusstore://app/",
  samsung: "samsungapps://ProductDetail/",
  meizu: "mstore://details?package_name=",
  lenovo: "http://market.lenovomm.com/details?id=",
  tmast: "tmast://appdetails?pname=",
  anzhi: "anzhimarket://details?id="
};

// deviceUtils.ts
export const getBrand = (userAgent: string): string => {
  const patterns = {
    apple: /iphone|ipad|ipod/i,
    huawei: /huawei|honor/i,
    oppo: /oppo|pacm00/i,
    vivo: /vivo/i,
    xiaomi: /mi\s|xiaomi|mix\s|redmi/i,
    samsung: /sm-/i,
    oneplus: /oneplus|le/i,
    meizu: /meizu/i
  };

  for (const [brand, pattern] of Object.entries(patterns)) {
    if (pattern.test(userAgent)) return brand;
  }
  
  return 'other';
};

// appRouter.ts
export class AppRouter {
  private readonly config: Required<AppConfig>;
  private readonly storeUrl: string;
  private readonly platform: string;
  
  constructor(options: AppConfig) {
    const app = getApp();
    this.platform = app.globalData.systemInfo.platform;
    
    // Set default timeout
    this.config = {
      ...options,
      timeout: options.timeout || 2000
    };

    // Determine store URL based on platform and device
    if (this.platform === 'ios') {
      this.storeUrl = `${STORE_SCHEMES.apple}${options.ios}`;
    } else {
      const brand = getBrand(app.globalData.systemInfo.model.toLowerCase());
      const storeScheme = STORE_SCHEMES[brand] || STORE_SCHEMES.tmast; // Default to TencentAppStore
      this.storeUrl = `${storeScheme}${options.package}`;
    }
  }

  public async openApp(): Promise<void> {
    return new Promise((resolve, reject) => {
      const startTime = Date.now();
      const visibilityProp = this.getVisibilityProp();
      
      if (!visibilityProp) {
        this.handleFailure();
        reject(new Error('Visibility API not supported'));
        return;
      }

      const visibilityHandler = () => {
        if (document[visibilityProp]) {
          document.removeEventListener(this.getVisibilityEvent(), visibilityHandler);
          resolve();
        }
      };

      document.addEventListener(this.getVisibilityEvent(), visibilityHandler);

      // Try to open app
      location.href = this.config.scheme;

      // Timeout check
      setTimeout(() => {
        const elapsed = Date.now() - startTime;
        if (elapsed < this.config.timeout + 200 && !document[visibilityProp]) {
          document.removeEventListener(this.getVisibilityEvent(), visibilityHandler);
          this.handleFailure();
          reject(new Error('App launch timeout'));
        }
      }, this.config.timeout);
    });
  }

  private handleFailure(): void {
    uni.showModal({
      title: '打开失败',
      content: '是否跳转到应用商店下载？',
      success: (res) => {
        if (res.confirm) {
          this.goToStore();
        }
      }
    });
  }

  private goToStore(): void {
    location.href = this.storeUrl;
  }

  private getVisibilityProp(): string | null {
    const props = ['hidden', 'msHidden', 'webkitHidden'];
    for (const prop of props) {
      if (typeof document[prop] !== 'undefined') {
        return prop;
      }
    }
    return null;
  }

  private getVisibilityEvent(): string {
    const events = {
      hidden: 'visibilitychange',
      msHidden: 'msvisibilitychange',
      webkitHidden: 'webkitvisibilitychange'
    };
    const prop = this.getVisibilityProp();
    return prop ? events[prop.replace('Hidden', '')] : 'visibilitychange';
  }
}

// usage-example.ts
const openMeituan = async () => {
  const router = new AppRouter({
    ios: APP_SCHEMES.meituan.ios,
    package: APP_SCHEMES.meituan.android,
    scheme: 'meituanapp://',
    timeout: 2000
  });

  try {
    await router.openApp();
    console.log('App opened successfully');
  } catch (error) {
    console.error('Failed to open app:', error);
  }
};